<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2018 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Released under the MIT License.
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------

namespace app\home\controller;

use think\Db;
use cmf\controller\HomeBaseController;
class CallbackController extends HomeBaseController
{

    /**
    *
    *回调地址
    **/
    public function payBack()
    {
        //接收数据，检测数据
        //$data = $this->request->param();
        $data = file_get_contents("php://input");
       
        //转成数组
        $data = json_decode(json_encode(simplexml_load_string($data,'SimpleXMLElement',LIBXML_NOCDATA)),true);

        if(!empty($data))
        {

            //判断结果
            if($data['return_code'] != 'SUCCESS')
            {
                WL([ 'msg' => '回调结果未成功', 'return_code' => $data['return_code'], 'return_msg' => $data['return_msg']],'wx_h5_pay');
                return;
            }

            //----------------------校验签名------------------------------
            //保存微信服务器返回的签名sign
            $data_sign = $data['sign'];
            //sign不参与签名算法
            unset($data['sign']);
            //生成签名
            $sign2 = $this->getSign2($data);
            if($sign2 != $data_sign)
            {
                WL([ 'msg' => '签名有误', 'data_sign' => $data_sign, 'sign2' => $sign2],'wx_h5_pay');
                return;
            }


            //付款成功，进行数据处理
            $courseModel = new \app\home\model\CourseModel();
            $orderModel = new \app\home\model\OrdersModel();
            $coursecodeModel = new \app\home\model\CourseCodeModel();
            $ckModel = new \app\home\model\CourseSkuModel();

            $order_number = $data['out_trade_no'];

           
            $order_info = $orderModel->checkMemberOrders($order_number);

            if(empty($order_info))
            {
                WL([ 'msg' => '不存在的用户订单', 'order_number' => $order_number],'wx_h5_pay');
                return;
            }


            //查看订单状态,如果已经是付款状态。就不需要再操作
            if($order_info['status'] != 0)
            {
                WL([ 'msg' => '该账单状态已被改变', 'order_number' => $order_number],'wx_h5_pay');
                $wx_msg = [
                'return_code' => 'SUCCESS',
                'return_msg' => 'OK',
                ];
                
                $res = $this->arrayToXml($wx_msg);
                return $res;
                
            }


            WL([ 'msg' => '订单金额对比'],'wx_h5_pay');
            //订单金额
            /*$money = $data['total_fee'] / 100;
            if($order_info['pay_money'] != $money)
            {
                WL([ 'msg' => '订单金额异常', 'pay_money' => $order_info['pay_money'], 'total_fee' => $money],'wx_h5_pay');
                return;
            }*/


            //开始修改订单状态，课程库存、课程销量
            Db::startTrans();

            $order_where = [
                ['order_id', '=', $order_info['order_id']],
                ['status', '=', 0],
            ];

            $update_order = [
                'status' => 1,
                'pay_time' => date('Y-m-d H:i:s'),
                'pay_voucher' => $data['transaction_id'],
            ];

            //修改订单状态
            $res = $orderModel->updateOrders($order_where, $update_order);
            if(empty($res))
            {
                WL([ 'msg' => '更新订单状态失败', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                Db::rollback();
                return;
            }

            $course_info = $courseModel->getCourseInfoDetails($order_info['course_id']);
           
            //增加课程库存和销量
            $course_where = [
                ['id', '=', $order_info['course_id']],
            ];

            $inventory_number = $course_info['inventory_number'] - 1;
            $sales_number = $course_info['sales_number'] + 1;

            $update_course = [
                'inventory_number' => $inventory_number,
                'sales_number' => $sales_number,
            ];

            $res = $courseModel->updateCourse($course_where, $update_course);
            if(empty($res))
            {
                WL([ 'msg' => '更新订单对应的课程信息失败', 'course_id' => $order_info['course_id']],'wx_h5_pay');
                Db::rollback();
                return;
            }

            //订单成功
            WL([ 'msg' => '订单支付成功', 'order_id' => $order_info['order_id']],'wx_h5_pay');
            Db::commit();

            //付款成功，通知消息
            WL([ 'msg' => '发送消息通知'],'wx_h5_pay');
            $notice_contro = new NoticeController();
            $send_data = [
                'first' => ['value'=>'您的订单已支付', 'color'=>"#173177"],
                'keyword1' => ['value'=> $order_info['order_number'], 'color'=>'#173177'],
                'keyword2' => ['value'=> $course_info['title'], 'color'=>'#173177'],
                'keyword3' => ['value'=> $order_info['add_time'], 'color'=>'#173177'],
                'keyword4' => ['value'=> $order_info['pay_money'], 'color'=>'#173177'],
                'remark' => ['value'=>'请在【我的-我的订单】查看订单', 'color'=>'#173177']
            ];
            WL([ 'msg' => '发送消息通知1'],'wx_h5_pay');
            $return_url = WEB_URL."/order";
            WL([ 'msg' => '发送消息通知2'],'wx_h5_pay');
            $notice_contro->sendNoticeMessage('fk', $send_data, $return_url, '', $order_info['member_id']);
            WL([ 'msg' => '发送消息完毕'],'wx_h5_pay');

            //查看用户是否存在邀请人
            $member_id = $order_info['member_id'];
            $memModel = new \app\home\model\MemberModel();
            $accessModel = new \app\home\model\MemberAccessModel();
            $member_info = $memModel->getMemberIdWhereMemberId($member_id, 'member_id, nickname, grade, parent');
            //无上级
            if(empty($member_info['parent']))
            {
                 WL([ 'msg' => '用户无上级'],'wx_h5_pay');
                //最近访问了谁
                $access_info = $accessModel->getMemberAccessOthers($member_id);

                 WL([ 'msg' => '查找最近访问了谁', 'info' => $access_info],'wx_h5_pay');
                if($access_info)
                {
                    //找出邀请人的邀请码，并绑定
                    $parent_member_info = $memModel->getMemberIdWhereMemberId($access_info['member_id'], 'member_id, open_id, invite');
                    WL([ 'msg' => '查找邀请人的邀请码', 'info' => $parent_member_info],'wx_h5_pay');


                    //绑定
                    $res = $memModel->updateMemberInfo($member_id, ['parent' => $parent_member_info['invite']]);
                    if(empty($res))
                    {
                        WL([ 'msg' => '用户绑定邀请人失败', 'member_id' => $member_id, 'parent_id' => $access_info['member_id']],'wx_h5_pay');
                    }else{
                        //绑定关系，提醒上级
                        $send_data = [
                            'first' => ['value'=>'您的团队新增了一名粉丝', 'color'=>"#173177"],
                            'keyword1' => ['value'=> $member_info['nickname'], 'color'=>'#173177'],
                            'keyword2' => ['value'=> $course_info['title'], 'color'=>'#173177'],
                            'keyword3' => ['value'=> $order_info['pay_money'], 'color'=>'#173177'],
                            'keyword4' => ['value'=> date('Y-m-d H:i:s'), 'color'=>'#173177'],
                            'remark' => ['value'=> '下级自购/推广您都可以获得收益', 'color'=>'#173177'],
                        ];
                        $return_url = WEB_URL."/my_team?type=1";
                        $notice_contro->sendNoticeMessage('xjgm', $send_data, $return_url, '', $parent_member_info['member_id']);
                    }
                }
            }


            //-----------------------------计算奖励分成----------------------------------
            WL([ 'msg' => '----------订单奖励分成---------'],'wx_h5_pay');
            if($order_info['commission'] > 0)
            {
                $oaModel = new \app\home\model\OrderAwardModel();
                //查找奖励表中，是否有订单奖励了。有就不继续跑了

                WL([ 'msg' => $order_info['order_id']],'wx_h5_pay');
                $list = $oaModel->checkOrderIdEarnings($order_info['order_id'],'id');

                WL([ 'msg' => '查找奖励结果'],'wx_h5_pay');
                if(!empty($list))
                {
                    WL([ 'msg' => '该订单已存在奖励数据', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                }else{
                    Db::startTrans();
                    $member_id = $order_info['member_id'];
                    $member_info = $memModel->getMemberIdWhereMemberId($member_id, 'member_id, grade, parent');

                    WL([ 'msg' => '计算一级奖励'],'wx_h5_pay');
                    $award_money_1 = editNumber($order_info['commission'] * $course_info['one_rebate']);
                    $one_data = [ 
                        'order_id' => $order_info['order_id'],
                        'award_type' => 1,//佣金
                        'award_rate' => $course_info['one_rebate'],
                        'money' => $award_money_1,
                    ];
                    //如果自己是顾问，自己拿佣金
                    if($member_info['grade'] >= 2)
                    {
                        $one_data['member_id'] = $order_info['member_id'];
                    }else{
                        //佣金给最近的上级顾问、星级、联创
                        if(!empty($member_info['parent']))
                        {
                            $recently_member_id = $this->checkMemberRecentlyParent($member_info['parent'], 2);
                        }
                        $one_data['member_id'] = empty($recently_member_id) ? 100000 : $recently_member_id;
                    }

                    WL([ 'msg' => '准备发放计算一级奖励'],'wx_h5_pay');
                    //开始添加
                    $res = $oaModel->addMemberOrderEarnings($one_data);
                    WL([ 'msg' => '已经发放一级奖励'],'wx_h5_pay');
                    if(empty($res))
                    {
                        WL([ 'msg' => '订单一级佣金添加失败', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                        Db::rollback();
                    }else{
                        //---------------------成功，管理奖给最近的上级星级、联创-----------------------------
                        WL([ 'msg' => '计算管理奖'],'wx_h5_pay');
                        $award_money_2 = editNumber($order_info['commission'] * $course_info['two_rebate']);
                        $two_data = [ 
                            'order_id' => $order_info['order_id'],
                            'award_type' => 2,//管理奖
                            'award_rate' => $course_info['two_rebate'],
                            'money' => $award_money_2,
                        ];


                        //如果自己是星级or联创，管理奖给自己
                        if($member_info['grade'] >= 3)
                        {
                            $two_data['member_id'] = $order_info['member_id'];
                        }else{
                            //如果不是，一级一级找上去
                            if(!empty($member_info['parent']))
                            {
                                $recently_member_id_2 = $this->checkMemberRecentlyParent($member_info['parent'], 3);
                            }
                
                            $two_data['member_id'] = empty($recently_member_id_2) ? 100000 : $recently_member_id_2;
                        }
                        
                        WL([ 'msg' => '确定发放给谁'],'wx_h5_pay');
                        //开始添加
                         WL([ 'msg' => '发放二级奖励'],'wx_h5_pay');
                        $res = $oaModel->addMemberOrderEarnings($two_data);
                        if(empty($res))
                        {
                            WL([ 'msg' => '订单二级佣金添加失败', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                            Db::rollback();
                        }else{
                            //修改-订单奖励状态
                            $order_where = [
                                ['order_id', '=', $order_info['order_id']]
                            ];

                            $update_order = [
                                'if_award' => 2,
                            ];
                            $orderModel->updateOrders($order_where, $update_order);
                            WL([ 'msg' => '订单佣金发放完毕', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                            Db::commit();
                        }
                    }
                }

            }else{
                WL([ 'msg' => '该比订单无佣金', 'order_id' => $order_info['order_id']],'wx_h5_pay');
            }




            //-------------------------------兑换码发货------------------------------------------------
            if($course_info['attend_type'] == 2)
            {
                //查找订单规格 兑换码
                $sku_info = $ckModel->getCourseAndSpecsSkuInfo($order_info['course_id'], $order_info['specs'], 'id, course_id');

                $date = date('Y-m-d H:i:s');
                $code_where = [
                    ['course_id', '=', $order_info['course_id']],
                    ['start_time', '<=', $date], 
                    ['end_time', '>=', $date],
                    ['status', '=', 1],
                    ['sku_id', '=', $sku_info['id']],
                    
                ];
                $code_info = $coursecodeModel->getCourseCodeInfo($code_where);
                //如果有兑换码，就开始绑定到当前订单上
                if(!empty($code_info))
                {
                    Db::startTrans();
                    //1.绑定到订单上
                    $order_code_where = [
                        ['order_id', '=', $order_info['order_id']],
                        ['status', '=', 1],
                    ];

                    $update_code_order = [
                        'status' => 2,
                        'dispatch_time' => date('Y-m-d H:i:s'),
                        'course_code_id' => $code_info['id'],
                    ];
                    $res = $orderModel->updateOrders($order_code_where, $update_code_order);
                    if(empty($res))
                    {
                        WL([ 'msg' => '订单发货失败', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                        //如果发货失败，等待定时任务，定时捞订单并发货。
                        Db::rollback();
                    }else{
                        //2.发货成功，修改兑换码状态
                        $code_where = [
                            ['id', '=', $code_info['id']],
                            ['course_id', '=', $code_info['course_id']],
                            ['status', '=', 1],
                            
                        ];

                        $code_update = [
                            'status' => 2,
                            'order_id' => $order_info['order_id'],
                            'issue_time' => date('Y-m-d H:i:s'),
                        ];
                        $res = $coursecodeModel->updateCourseCodeWhereId($code_where, $code_update);
                        if(empty($res))
                        {
                            WL([ 'msg' => '更新订单绑定的兑换码状态失败', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                            //如果发货失败，等待定时任务，定时捞订单并发货。
                            Db::rollback();
                        }else{
                             WL([ 'msg' => '订单发货成功，绑定兑换码OK', 'order_id' => $order_info['order_id']],'wx_h5_pay');
                        }
                        Db::commit();

                        //发货成功，通知消息
                        $send_data = [
                            'first' => ['value'=>'您的订单已发货', 'color'=>"#173177"],
                            'keyword1' => ['value'=> $order_info['order_number'], 'color'=>'#173177'],
                            'keyword2' => ['value'=> $order_info['add_time'], 'color'=>'#173177'],
                            'keyword3' => ['value'=> '无', 'color'=>'#173177'],
                            'keyword4' => ['value'=> '无', 'color'=>'#173177'],
                            'keyword5' => ['value'=> $order_info['site'], 'color'=>'#173177'],
                            'remark' => ['value'=>'您的课程已开通，点击查看上课详情', 'color'=>'#173177']
                        ];
                        $return_url = WEB_URL."/order_details?order_id=".$order_info['order_id'];
                        $notice_contro->sendNoticeMessage('fh', $send_data, $return_url, '', $order_info['member_id']);
                    }
                }
            }

            WL([ 'msg' => '---订单支付成功---', 'order_id' => $order_info['order_id']],'wx_h5_pay');


            //告诉微信，成功了
            $wx_msg = [
                'return_code' => 'SUCCESS',
                'return_msg' => 'OK',
            ];
            
            $res = $this->arrayToXml($wx_msg);
            return $res;

        }else{
            //回调付款失败，就记录日志
            WL([ 'msg' => '交易失败'],'wx_h5_pay');
            return;
        }
    }


    /**
    *
    *
    **/
        /*
    生成签名
    */
    protected function getSign2($Obj)
    {
        foreach ($Obj as $k => $v)
        {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false, true);
        //echo "【string】 =".$String."</br>";
        //签名步骤二：在string后加入KEY
        $String = $String."&key=ce0bfd15059b68d67688884d7a3d3e8c";
//        echo "<textarea style='width: 50%; height: 150px;'>$String</textarea> <br />";
        //签名步骤三：MD5加密
        WL($String, 'sign');
        $result_ = strtoupper(md5($String));
        return $result_;
    }


    //将数组转成uri字符串
    protected function formatBizQueryParaMap($paraMap, $urlencode, $strtolower)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
                $v = urlencode($v);
            }

            if($strtolower)
            {
                $buff .= $k . "=" . $v . "&";
            }else{
                $buff .= strtolower($k) . "=" . $v . "&";
            }
            
        }
        $reqPar;
        if (strlen($buff) > 0)
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }



    //数组转xml
    protected function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }


   

    //用户最近-顾问、星级
    protected function checkMemberRecentlyParent($invite, $grade = 2)
    {
        $memModel = new \app\home\model\MemberModel();

        //找上级
        $info = $memModel->getMemberParentInfosAward($invite, 'member_id, grade, parent, invite');
        if(empty($info))
        {
            return false;
        }

        //上级的等级 和 要求的等级比较
        if($info['grade'] < $grade)
        {
            //存在上级，继续往上找
            if($info['parent'] != '')
            {
                $res = $this->checkMemberRecentlyParent($info['parent'], $grade);
                return $res;
            }else{
                return false;
            }
        }else{
            return $info['member_id'];
        }

    }


    public function test()
    {
        //WL(['msg' => '引入控制器'], 'send_msg');
        echo 'a';
        $notice_contro = new NoticeController();

        //WL(['msg' => '组装数据'], 'send_msg');
        $send_data = [
            'first' => ['value'=>'您的订单已支付', 'color'=>"#173177"],
            'keyword1' => ['value'=> 'aaaaa', 'color'=>'#173177'],
            'keyword2' => ['value'=> 'bbbbbb', 'color'=>'#173177'],
            'keyword3' => ['value'=> 'ccccc', 'color'=>'#173177'],
            'keyword4' => ['value'=> 'dddddd', 'color'=>'#173177'],
            'remark' => ['value'=>'请在【我的-我的订单】查看订单', 'color'=>'#173177']
        ];

        //WL(['msg' => 'url'], 'send_msg');
        $return_url = "https://qmyx.fenchuang100.com/order";

        //WL(['msg' => '开始发送'], 'send_msg');
        $notice_contro->sendNoticeMessage('fk', $send_data, $return_url, '', 100109);
    }
}